\section{Source/Math.c}


\begin{footnotesize}\begin{alltt}
00001 \textcolor{preprocessor}{#include <math.h>}
00002 \textcolor{preprocessor}{#include <stdlib.h>}
00003 \textcolor{preprocessor}{#include <string.h>}
00004 \textcolor{preprocessor}{#include <stdio.h>}
00005 \textcolor{preprocessor}{#include "Math.h"}
00006 
00007 \textcolor{comment}{/* Math library created by Daniel White}
00008 \textcolor{comment}{    Various math functions that could be useful for game developement (and then s
      ome more)}
00009 \textcolor{comment}{*/}
00010 
00011 \textcolor{comment}{/* Globals */}
00012 \textcolor{keywordtype}{int} *Math\_PrimeCache=NULL;
00013 \textcolor{keywordtype}{int} Math\_PrimeCacheSize=0;
00014 
00015 \textcolor{comment}{/* Functions */}
00016 
00017 \textcolor{keywordtype}{int} Math\_GetFirstNPrimes(\textcolor{keywordtype}{int} Amount, \textcolor{keywordtype}{int} *Array)
00018 \{   
00019     \textcolor{keywordflow}{if} (Amount<=Math\_PrimeCacheSize)
00020     \{
00021         memcpy(Array, Math\_PrimeCache, Amount);
00022         \textcolor{keywordflow}{return} 0;
00023     \}
00024     
00025     \textcolor{keywordtype}{int} UpdateCache, *TempPointer=realloc(Math\_PrimeCache, (Amount+1)*\textcolor{keyword}{sizeof}(Math
      \_PrimeCache));
00026     
00027     \textcolor{keywordflow}{if} (TempPointer==NULL)
00028         UpdateCache=0;
00029     \textcolor{keywordflow}{else}
00030     \{
00031         UpdateCache=1;
00032         Math\_PrimeCacheSize=Amount;
00033         Math\_PrimeCache=TempPointer;
00034     \}
00035     
00036     \textcolor{keywordtype}{double} A=2, B=4;
00037     \textcolor{keywordflow}{while}(A!=B)
00038     \{
00039         \textcolor{keywordflow}{if} (((\textcolor{keywordtype}{int})(B/log(B)))<Amount)
00040         \{
00041             A=B;
00042             B*=1.15;
00043         \}
00044         \textcolor{keywordflow}{if} (((\textcolor{keywordtype}{int})(B/log(B)))>Amount)
00045             B*=0.85;
00046         \textcolor{keywordflow}{if} (((\textcolor{keywordtype}{int})(B/log(B)))==Amount)
00047             A=B;
00048     \}
00049     \textcolor{keywordtype}{long} Max=(long)A;
00050     
00051     \textcolor{keywordtype}{long} X=3, X2, Y, AmountFound=0, SqrtMax=sqrt(Max);
00052     
00053     \textcolor{keywordtype}{int} *Numbers=calloc(Max, \textcolor{keyword}{sizeof}(Numbers));
00054     \textcolor{keywordflow}{if} (Numbers==NULL)
00055         \textcolor{keywordflow}{return} 1;
00056     
00057     Array[0]=2;
00058     \textcolor{keywordflow}{if} (UpdateCache)
00059         Math\_PrimeCache[0]=2;
00060     
00061     \textcolor{keywordflow}{while}(X<SqrtMax)
00062     \{
00063         \textcolor{keywordflow}{if} (Numbers[X]!=1)
00064         \{
00065             ++AmountFound;
00066             \textcolor{keywordflow}{if} (UpdateCache)
00067                 Math\_PrimeCache[AmountFound]=X;
00068             Array[AmountFound]=X;
00069             
00070             X2=X<<1;
00071             \textcolor{keywordflow}{for}(Y=X;Y<Max;Y+=X2)
00072                 Numbers[Y]=1;
00073         \}
00074         X+=2;
00075     \}
00076     
00077     \textcolor{keywordflow}{while}(AmountFound<Amount)
00078     \{
00079         \textcolor{keywordflow}{if} (Numbers[X]!=1)
00080         \{
00081             ++AmountFound;
00082             \textcolor{keywordflow}{if} (UpdateCache)
00083                 Math\_PrimeCache[AmountFound]=X;
00084             Array[AmountFound]=X;
00085         \}
00086         X+=2;
00087     \}
00088     
00089     free(Numbers);
00090     
00091     \textcolor{keywordflow}{return} 0;
00092 \}
00093 
00094 \textcolor{keywordtype}{int} Math\_GetFirstNPrimesLowMemory(\textcolor{keywordtype}{int} Amount, \textcolor{keywordtype}{int} *Array)
00095 \{   
00096     \textcolor{keywordflow}{if} (Amount<=Math\_PrimeCacheSize)
00097     \{
00098         memcpy(Array, Math\_PrimeCache, Amount);
00099         \textcolor{keywordflow}{return} 0;
00100     \}
00101     
00102     Array[0]=2;
00103     Array[1]=3;
00104     \textcolor{keywordtype}{int} Number=5, Found=2, Divisor, SqrtNumber, IsPrime;
00105     \textcolor{keywordflow}{for}(;Found<Amount;)
00106     \{
00107         SqrtNumber=sqrt(Number);
00108         IsPrime=1;
00109         \textcolor{keywordflow}{for}(Divisor=3;Divisor<=SqrtNumber;Divisor+=2)
00110         \{
00111             \textcolor{keywordflow}{if} (Number%Divisor==0)
00112             \{
00113                 IsPrime=0;
00114                 Divisor=SqrtNumber;
00115             \}
00116         \}
00117         \textcolor{keywordflow}{if} (IsPrime)
00118         \{
00119             Array[Found]=Number;
00120             ++Found;
00121         \}
00122         
00123         Number+=2;
00124         \textcolor{keywordflow}{if} (Found==Amount)
00125             \textcolor{keywordflow}{return} 0;
00126             
00127         SqrtNumber=sqrt(Number);
00128         IsPrime=1;
00129         \textcolor{keywordflow}{for}(Divisor=3;Divisor<=SqrtNumber;Divisor+=2)
00130         \{
00131             \textcolor{keywordflow}{if} (Number%Divisor==0)
00132             \{
00133                 IsPrime=0;
00134                 Divisor=SqrtNumber;
00135             \}
00136         \}
00137         \textcolor{keywordflow}{if} (IsPrime)
00138         \{
00139             Array[Found]=Number;
00140             ++Found;
00141         \}
00142             
00143         Number+=4;
00144     \}
00145     
00146     \textcolor{keywordflow}{return} 0;
00147 \}
00148 
00149 \textcolor{keywordtype}{int} Math\_IsPrime(\textcolor{keywordtype}{int} Number)
00150 \{
00151     \textcolor{keywordtype}{int} Amount=100;
00152     \textcolor{keywordtype}{int} TempArray[Amount];
00153     \textcolor{keywordflow}{if} (Math\_PrimeCacheSize<Amount)
00154         Math\_GetFirstNPrimes(Amount, TempArray);
00155     
00156     \textcolor{comment}{/* Divide by primes */}
00157     \textcolor{keywordtype}{int} PrimeIndex;
00158     \textcolor{keywordflow}{for}(PrimeIndex=0;PrimeIndex<Math\_PrimeCacheSize;++PrimeIndex)
00159     \{
00160         \textcolor{keywordflow}{if} (Number==Math\_PrimeCache[PrimeIndex])
00161             \textcolor{keywordflow}{return} 1;
00162         \textcolor{keywordflow}{else}
00163         \{
00164             \textcolor{keywordflow}{while} (Number%Math\_PrimeCache[PrimeIndex]==0)
00165                 Number/=Math\_PrimeCache[PrimeIndex];
00166         \}
00167     \}
00168     
00169     \textcolor{keywordflow}{if} (Number==1)
00170         \textcolor{keywordflow}{return} 0;
00171     
00172     \textcolor{comment}{/* Now try trial division */}
00173     \textcolor{keywordtype}{int} SqrtNumber=sqrt(Number), Divisor;
00174     \textcolor{keywordflow}{for}(Divisor=3;Divisor<=SqrtNumber;Divisor+=2)
00175     \{
00176         \textcolor{keywordflow}{if} (Number%Divisor==0)
00177             \textcolor{keywordflow}{return} 0;
00178     \}
00179     
00180     \textcolor{keywordflow}{return} 1;
00181 \}
00182 
00183 \textcolor{keywordtype}{int} Math\_GCD(\textcolor{keywordtype}{int} Number0, \textcolor{keywordtype}{int} Number1)
00184 \{
00185     \textcolor{keywordtype}{int} Temp;
00186     \textcolor{keywordflow}{while}(Number1!=0)
00187     \{
00188         Temp=Number1;
00189         Number1=Number0%Number1;
00190         Number0=Temp;
00191     \}
00192     \textcolor{keywordflow}{return} Number0;
00193 \}
00194 
00195 \textcolor{keyword}{inline} \textcolor{keywordtype}{int} Math\_LCM(\textcolor{keywordtype}{int} Number0, \textcolor{keywordtype}{int} Number1)
00196 \{
00197     \textcolor{keywordflow}{return} abs(Number0*Number1)/Math\_GCD(Number0, Number1);
00198 \}
00199 
00200 \textcolor{keywordtype}{int} Math\_DigitalSum(\textcolor{keywordtype}{int} Number)
00201 \{
00202     \textcolor{keywordtype}{int} Sum=0;
00203     
00204     \textcolor{keywordflow}{while}(Number>0)
00205     \{
00206         Sum+=Number%10;
00207         Number/=10;
00208     \}
00209     
00210     \textcolor{keywordflow}{return} Sum;
00211 \}
00212 
00213 \textcolor{keywordtype}{int} Math\_DigitalRoot(\textcolor{keywordtype}{int} Number)
00214 \{
00215     \textcolor{keywordflow}{if} (Number%9==0)
00216         \textcolor{keywordflow}{return} 9;
00217     \textcolor{keywordflow}{else}
00218         \textcolor{keywordflow}{return} Number%9;
00219 \}
00220 
00221 \textcolor{keyword}{inline} \textcolor{keywordtype}{float} Math\_AngleY(\textcolor{keywordtype}{float} Angle)
00222 \{
00223     \textcolor{keywordflow}{if}(Angle < 90.0)
00224         \textcolor{keywordflow}{return} -cos((\textcolor{keywordtype}{float})Math_DegToRad(Angle));
00225     \textcolor{keywordflow}{if}(Angle < 180.0)
00226         \textcolor{keywordflow}{return} sin((\textcolor{keywordtype}{float})Math_DegToRad(Angle-90.0));
00227     \textcolor{keywordflow}{if}(Angle < 270.0)
00228         \textcolor{keywordflow}{return} cos((\textcolor{keywordtype}{float})Math_DegToRad(Angle-180.0));
00229     \textcolor{keywordflow}{return} -sin((\textcolor{keywordtype}{float})Math_DegToRad(Angle-270.0));
00230 \}
00231 
00232 \textcolor{keyword}{inline} \textcolor{keywordtype}{float} Math\_AngleX(\textcolor{keywordtype}{float} Angle)
00233 \{
00234     \textcolor{keywordflow}{if}(Angle < 90.0)
00235         \textcolor{keywordflow}{return} sin((\textcolor{keywordtype}{float})Math_DegToRad(Angle));
00236     \textcolor{keywordflow}{if}(Angle < 180.0)
00237         \textcolor{keywordflow}{return} cos((\textcolor{keywordtype}{float})Math_DegToRad(Angle-90.0));
00238     \textcolor{keywordflow}{if}(Angle < 270.0)
00239         \textcolor{keywordflow}{return} -sin((\textcolor{keywordtype}{float})Math_DegToRad(Angle-180.0));
00240     \textcolor{keywordflow}{return} -cos((\textcolor{keywordtype}{float})Math_DegToRad(Angle-270.0));
00241 \}
00242 
00243 \textcolor{keyword}{inline} \textcolor{keywordtype}{float} Math\_XYAngle(\textcolor{keywordtype}{float} X1, \textcolor{keywordtype}{float} Y1, \textcolor{keywordtype}{float} X2, \textcolor{keywordtype}{float} Y2)
00244 \{
00245     \textcolor{keywordflow}{return} Math_RadToDeg(atan2(Y2-Y1, X2-X1))+90;
00246 \}
00247 
00248 \textcolor{keywordtype}{float} Math\_NormaliseAngle(\textcolor{keywordtype}{float} Angle)
00249 \{
00250     \textcolor{keywordflow}{while}(Angle >= 360.0)
00251         Angle -= 360.0;
00252     \textcolor{keywordflow}{while}(Angle < 0.0)
00253         Angle += 360.0;
00254     \textcolor{keywordflow}{return} Angle;
00255 \}
00256 
00257 \textcolor{keywordtype}{int} Math\_PrimeFactors(\textcolor{keywordtype}{int} Number, \textcolor{keywordtype}{int} **Factors)
00258 \{
00259     \textcolor{keywordtype}{int} TempPrimes[10];
00260     Math\_GetFirstNPrimes(10, TempPrimes);
00261     
00262     \textcolor{keywordtype}{int} FactorCount=0, PrimeIndex, *TempPointer;
00263     
00264     \textcolor{keywordflow}{for}(PrimeIndex=0;PrimeIndex<Math\_PrimeCacheSize;++PrimeIndex)
00265     \{
00266         \textcolor{keywordflow}{while} (Number%Math\_PrimeCache[PrimeIndex]==0)
00267         \{
00268             Number/=Math\_PrimeCache[PrimeIndex];
00269             ++FactorCount;
00270             
00271             TempPointer=realloc((*Factors), FactorCount*\textcolor{keyword}{sizeof}(*Factors));
00272             \textcolor{keywordflow}{if} (TempPointer==NULL)
00273                 \textcolor{keywordflow}{return} -1;
00274             (*Factors)=TempPointer;
00275             (*Factors)[FactorCount-1]=Math\_PrimeCache[PrimeIndex];
00276         \}
00277     \}
00278     
00279     \textcolor{keywordtype}{int} Divisor;
00280     \textcolor{keywordflow}{for}(Divisor=3;Divisor<=Number;Divisor+=2)
00281     \{
00282         \textcolor{keywordflow}{while} (Number%Divisor==0)
00283         \{
00284             Number/=Divisor;
00285             ++FactorCount;
00286             
00287             TempPointer=realloc((*Factors), FactorCount*\textcolor{keyword}{sizeof}(*Factors));
00288             \textcolor{keywordflow}{if} (TempPointer==NULL)
00289                 \textcolor{keywordflow}{return} -1;
00290             (*Factors)=TempPointer;
00291             (*Factors)[FactorCount-1]=Divisor;          
00292         \}
00293         
00294         \textcolor{keywordflow}{if} (Number==1)
00295             \textcolor{keywordflow}{return} FactorCount;
00296     \}
00297     
00298     \textcolor{keywordflow}{return} FactorCount;
00299 \}
00300 
00301 \textcolor{keywordtype}{int} Math\_PrimeFactorCount(\textcolor{keywordtype}{int} Number)
00302 \{
00303     \textcolor{keywordtype}{int} *PrimeFactors=NULL;
00304     \textcolor{keywordtype}{int} PrimeAmount=Math\_PrimeFactors(Number, &PrimeFactors);
00305     free(PrimeFactors); 
00306     \textcolor{keywordflow}{return} PrimeAmount;
00307 \}
00308 
00309 \textcolor{keywordtype}{int} Math\_FactorCount(\textcolor{keywordtype}{int} Number)
00310 \{
00311     \textcolor{keywordtype}{int} *PrimeFactors=NULL;
00312     \textcolor{keywordtype}{int} PrimeAmount=Math\_PrimeFactors(Number, &PrimeFactors);
00313     \textcolor{keywordflow}{if} (PrimeAmount==-1)
00314         \textcolor{keywordflow}{return} -1;
00315     
00316     \textcolor{keywordtype}{int} Amount=1, Last=0, Index, Count=1;
00317     \textcolor{keywordflow}{for}(Index=0;Index<PrimeAmount;++Index)
00318     \{
00319         \textcolor{keywordflow}{if} (PrimeFactors[Index]!=Last)
00320         \{
00321             Amount*=Count;
00322             
00323             Last=PrimeFactors[Index];
00324             Count=2;
00325         \}
00326         \textcolor{keywordflow}{else}
00327             ++Count;
00328     \}
00329     Amount*=Count;
00330     
00331     free(PrimeFactors); 
00332     \textcolor{keywordflow}{return} Amount;
00333 \}
00334 
00335 \textcolor{keywordtype}{void} Math\_ClearCache()
00336 \{
00338         free(Math\_PrimeCache);
00339     Math\_PrimeCache=NULL;
00340     Math\_PrimeCacheSize=0;
00341 \}
\end{alltt}\end{footnotesize}
